﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Diagnostics;
using System.Diagnostics.Contracts;

namespace WindowsGame1
{
    /// <summary>
    /// 
    /// </summary>
    ///<remarks>reference http://stackoverflow.com/a/4998878/57883</remarks>
    public class DungeonGenerator<T>
        where T : WindowsGame1.DungeonGames.ITile
    {
        Random _rand;
        //Rectangle _rect;
        T[,] _tiles;
        public DungeonGenerator(int seed, Microsoft.Xna.Framework.Rectangle rect, IEnumerable<T> availableTiles)
        {
            Debug.Assert(rect.Height > 4);
            Debug.Assert(rect.Width > 4);
            _rand = new Random(seed);
            //_rect = rect;
            _tiles = GenerateDungeon(rect, availableTiles);
        }

        T[,] GenerateDungeon(Microsoft.Xna.Framework.Rectangle rect, IEnumerable<T> availableTiles)
        {
            var result = new T[rect.Height, rect.Width];
            var tiles = _tiles.GetEnumerator();
            var entrance = availableTiles.FirstOrDefault(t => t.IsEntrance);
            if (entrance != null)
            {
                var plot=GetRandomEmptyLocation(result);
                result[plot.Item1, plot.Item2] = entrance;
            }
            var exit = availableTiles.FirstOrDefault(t => t.IsExit);
            if (exit != null)
            {
                var plot = GetRandomEmptyLocation(result);
                result[plot.Item1, plot.Item2] = exit;
            }

            for (int x = 0; x < rect.Width; x++)
                for (int y = 0; y < rect.Height; y++)
                {
                    
                    T[,] copy =(T[,]) result.Clone();
                    do
                    {
                        copy[x, y] = availableTiles.GetRandom(_rand);
                        result = copy;
                    } while (!IsValid(copy));

                }

            return result;
        }

        /// <summary>
        /// validate that entrance and exit are not blocked
        /// assuming null tiles are passable
        /// </summary>
        /// <param name="copy"></param>
        /// <returns></returns>
        private bool IsValid(T[,] copy)
        {
            return true;
        }


        /// <summary>
        /// Add a specific tile at a random location
        /// </summary>
        /// <param name="result"></param>
        /// <param name="tile"></param>
        /// <returns></returns>
        Tuple<int, int> GetRandomEmptyLocation(T[,] dungeon)
        {
            //assume there is an empty tile left

            int nextX;
            int nextY;

            do
            {
#warning no timeout means endless loop
                nextX = _rand.Next(dungeon.GetLowerBound(0), dungeon.GetUpperBound(0));
                nextY = _rand.Next(dungeon.GetLowerBound(1), dungeon.GetUpperBound(1));

            } while (dungeon[nextX, nextY] != null);
            
            
            
            return Tuple.Create(nextX,nextY);
        }



    }
}
